package org.moonshot.cvm;

import java.util.HashMap;

/**
 * Implements the four basic singletons in the Chatty environment; true, false, nil, and NaN.
 * @author Tiogshi Laj
 */
public class ChattyBasic implements I_ChattyClass, I_ChattyCompatible
{
	public static enum Kind {
		TRUE, FALSE, NIL, NAN
	}
	
	private static final HashMap<String, METHOD> methods = new HashMap<String, METHOD> ();
	private static enum METHOD {
		IS("is:"), EQUALS("equals:"), ISTRUE("isTrue"), ISFALSE("isFalse"), ISNIL("isNil"), ISNAN("isNaN");
		
		private METHOD(String aSignature)
		{
			methods.put(aSignature, this);
		}
		
		public static METHOD get(String aSignature)
		{
			return methods.get (aSignature);
		}
	}
	
	protected final Kind me;
	
	public ChattyBasic(Kind aType)
	{
		me = aType;
	}
	
    public Object callInstance (ChattyVM aVM, Object aInstance, String aMethod, ChattyStack aStack, int nParams) throws CVMRuntimeException
    {
    	final METHOD method = METHOD.get (aMethod);
    	if( method == null )
        	throw new CVMRuntimeException ("Method "+aMethod+" not defined for this object");
    	
    	switch (method)
    	{
    	case IS:
    		if( aInstance instanceof ChattyNumber )
    			return aVM.convertObject(((ChattyNumber)aInstance).doEquals(aStack.at(1)));
			return aInstance == aStack.at(1);
			
    	case EQUALS:
	    	return doEquals(aVM, aInstance, aStack.at(1));
    		
    	case ISTRUE:
	    	return aVM.convertObject(aInstance instanceof ChattyBasic ? ((ChattyBasic)aInstance).me == Kind.TRUE : false);
    		
    	case ISFALSE:
	    	return aVM.convertObject(aInstance instanceof ChattyBasic ? ((ChattyBasic)aInstance).me != Kind.TRUE : true);
    		
    	case ISNIL:
	    	return aVM.convertObject(aInstance instanceof ChattyBasic ? ((ChattyBasic)aInstance).me == Kind.NIL : false);
    		
    	case ISNAN:
	    	return aVM.convertObject(aInstance instanceof ChattyBasic ? (((ChattyBasic)aInstance).me == Kind.NIL || ((ChattyBasic)aInstance).me == Kind.NAN) : false);
    	}
    	
    	return null;
    }
	
    protected Object doEquals (ChattyVM aVM, Object a, Object b)
    {
	    return aVM.FALSE;
    }
    
	public I_ChattyClass getSuperclass (ChattyVM aVM)
    {
	    return aVM.NIL;
    }
	
    public I_ChattyClass identifySelfClass (ChattyVM aVM)
    {
	    return this;
    }
}
